package com.yingsheng.bi.hks.service.contract;

import com.qiyuesuo.sdk.v2.SdkClient;
import com.qiyuesuo.sdk.v2.bean.*;
import com.qiyuesuo.sdk.v2.exception.BaseSdkException;
import com.qiyuesuo.sdk.v2.json.JSONUtils;
import com.qiyuesuo.sdk.v2.request.ContractDraftRequest;
import com.qiyuesuo.sdk.v2.request.ContractMiniappTicketRequest;
import com.qiyuesuo.sdk.v2.request.ContractMiniappViewTicketRequest;
import com.qiyuesuo.sdk.v2.request.DocumentDownloadRequest;
import com.qiyuesuo.sdk.v2.response.MiniappTicketResult;
import com.qiyuesuo.sdk.v2.response.SdkResponse;
import com.qiyuesuo.sdk.v2.utils.IOUtils;
import com.yingsheng.bi.hks.basic.PUser;
import com.yingsheng.bi.hks.basic.enums.EnumConst;
import com.yingsheng.bi.hks.basic.enums.XjyOssEnum;
import com.yingsheng.bi.hks.basic.exception.ServiceRuntimeException;
import com.yingsheng.bi.hks.basic.utils.Subject;
import com.yingsheng.bi.hks.basic.utils.Utils;
import com.yingsheng.bi.hks.bo.ContractsBo;
import com.yingsheng.bi.hks.dto.contract.*;
import com.yingsheng.bi.hks.mapping.ContractsMgmtMappings;
import com.yingsheng.bi.hks.repository.dao.po.Contracts;
import com.yingsheng.bi.hks.repository.dao.po.Users;
import com.yingsheng.bi.hks.repository.dao.service.ContractsDaoService;
import com.yingsheng.bi.hks.repository.dao.service.UsersDaoService;
import com.yingsheng.bi.hks.repository.redis.RedisService;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class ContracMgmtService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private ContractsDaoService contractsDaoService;

    @Autowired
    private UsersDaoService usersDaoService;

    /**
     * 创建-发送
     *
     * @param req
     * @return
     */
    public ContractOneSendRes templateOneSend(ContractOneSendReq req) {

        //获取甲方用户信息
        Users partyA = usersDaoService.selectByUserId(req.getPartyAId());
        //获取乙方用户信息
        Users partyB = usersDaoService.selectByUserId(req.getPartyBId());

        ContractOneSendRes res = new ContractOneSendRes();
        if (!EnumConst.ContractType.CONTRACT_TYPE_0.equals(req.getType())) {
            throw new ServiceRuntimeException("合同类型错误！");
        }
        SdkClient sdkClient = createQYSClient();

        // 合同基本参数
        Contract contract = new Contract();
        contract.setSubject("欣佳源家政管理制合同");
        contract.setCategory(new Category(req.getCategoryId()));
        contract.setBizId(Utils.genUUid());
        contract.setSend(true);
        contract.setOrdinal(true);
        // 个人
        Signatory signatory1 = new Signatory();
        signatory1.setTenantName(partyA.getName());
        signatory1.setTenantType("PERSONAL");
        signatory1.setReceiver(new User(partyA.getName(), partyA.getMobile(), "MOBILE"));
        signatory1.setSerialNo(1);

        // 公司
        Signatory signatory2 = new Signatory();
        signatory2.setTenantName("宁波欣佳源家政服务有限公司");
        signatory2.setTenantType("COMPANY");
        signatory2.setReceiver(new User(partyB.getName(), partyB.getMobile(), "MOBILE"));
        signatory2.setSerialNo(3);
        Action action = new Action("COMPANY", 1);
        signatory2.addAction(action);
        // 设置签署方
        contract.addSignatory(signatory1);
        contract.addSignatory(signatory2);
        // 设置模板参数
        contract.addTemplateParam(new TemplateParam("Sn", req.getSn()));
        contract.addTemplateParam(new TemplateParam("firstParty", partyA.getName()));
        contract.addTemplateParam(new TemplateParam("gou1", req.getGou1()));
        contract.addTemplateParam(new TemplateParam("gou2", req.getGou2()));
        contract.addTemplateParam(new TemplateParam("gou3", req.getGou3()));
        contract.addTemplateParam(new TemplateParam("gou4", req.getGou4()));
        contract.addTemplateParam(new TemplateParam("gou5", req.getGou5()));
        contract.addTemplateParam(new TemplateParam("address", req.getAddress()));
        contract.addTemplateParam(new TemplateParam("startDate", req.getStartDate()));
        contract.addTemplateParam(new TemplateParam("endDate", req.getEndDate()));
        contract.addTemplateParam(new TemplateParam("shiyongjin", req.getShiyongjin()));
        contract.addTemplateParam(new TemplateParam("genghuancishu", req.getGenghuancishu()));
        contract.addTemplateParam(new TemplateParam("laowubaochou", req.getLaowubaochou()));
        contract.addTemplateParam(new TemplateParam("faxinri", req.getFaxinri()));
        contract.addTemplateParam(new TemplateParam("faxinren", req.getFaxinren()));
        contract.addTemplateParam(new TemplateParam("genghuan1", req.getGenghuan1()));
        contract.addTemplateParam(new TemplateParam("genghuan2", req.getGenghuan2()));
        contract.addTemplateParam(new TemplateParam("diaohuan", req.getDiaohuan()));
        contract.addTemplateParam(new TemplateParam("chaoqi", req.getChaoqi()));
        contract.addTemplateParam(new TemplateParam("daigangfei", req.getDaigangfei()));
        contract.addTemplateParam(new TemplateParam("guanlifei", req.getGuanlifei()));
        contract.addTemplateParam(new TemplateParam("citui", req.getCitui()));
        contract.addTemplateParam(new TemplateParam("xiujiatian", req.getXiujiatian()));
        contract.addTemplateParam(new TemplateParam("xiujianian", req.getXiujianian()));
        contract.addTemplateParam(new TemplateParam("idCardNo", req.getIdCardNo()));
        contract.addTemplateParam(new TemplateParam("phone", req.getPhone()));
        // 创建合同
        ContractDraftRequest request = new ContractDraftRequest(contract);
        String response = sdkClient.service(request);
        SdkResponse<Contract> responseObj = JSONUtils.toQysResponse(response, Contract.class);
        // 返回结果
        if (responseObj.getResponseCode().equals("00000000")) {
            Contract result = responseObj.getResult();
            String str = JSONUtils.toJson(result);

            //初始化本地合同
            Contracts contracts = new Contracts();
            contracts.setNo(result.getSn());
            contracts.setType(req.getType());
            contracts.setTitle(result.getDocuments().get(0).getId().toString());
            contracts.setState(EnumConst.ContractState.CONTRACT_STATE_0);
            contracts.setPartyIdA(req.getPartyAId());
            contracts.setPartyIdB(req.getPartyBId());
            contracts.setBegDate(strToDate(req.getStartDate()));
            contracts.setEndDate(strToDate(req.getEndDate()));
            contracts.setContractId(result.getId());
            contracts.setDocumenId(result.getDocuments().get(0).getId());
            contracts.setPartySignA("0");
            contracts.setPartySignB("0");
            contracts.setPartySignC("0");
            contractsDaoService.insert(contracts);

            res.setContractId(result.getId());
            res.setDocumentId(result.getDocuments().get(0).getId());
            log.info("创建合同成功: " + str);
        } else {
            log.info("请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
            res.setErrorCode("9999");
            res.setErrorMsg(responseObj.getMessage());
        }

        return res;
    }

    public CreateContractTokenRes createContractToken(CreateContractTokenReq req) {

        PUser user = Subject.get();

        //获取合同信息
        Contracts contracts = contractsDaoService.qryById(req.getContractsId());
        //获取甲方用户信息
        Users signUser = usersDaoService.selectByUserId(user.getId());

        CreateContractTokenRes res = new CreateContractTokenRes();
        String token = (String) redisService.get(req.getContractsId());
        if (StringUtil.isNullOrEmpty(token)) {
            SdkClient sdkClient = createQYSClient();
            ContractMiniappTicketRequest request = new ContractMiniappTicketRequest(contracts.getContractId(), new User(signUser.getMobile(), "MOBILE"));
            String response = null;
            try {
                response = sdkClient.service(request);
            } catch (Exception e) {
                throw new BaseSdkException("调用接口错误，错误原因：" + e.getMessage());
            }
            SdkResponse<MiniappTicketResult> result = JSONUtils.toQysResponse(response, MiniappTicketResult.class);
            if (!result.getCode().equals(0)) {
                throw new BaseSdkException("获取合同签署Ticket失败，失败原因：" + result.getCode() + "," + result.getMessage());
            }
            token = result.getResult().getTicket();
            redisService.set(req.getContractsId().toString(), token, 300L);
            log.info("获取合同签署Ticket成功，Ticket:" + result.getResult().getTicket());
        }
        res.setToken(token);
        return res;
    }

    public ContractDownLoadRes contractDownLoad(ContractDownLoadReq req) {

        //获取合同信息
        Contracts contracts = contractsDaoService.qryById(req.getId());
        SdkClient sdkClient = createQYSClient();
        DocumentDownloadRequest request = new DocumentDownloadRequest(contracts.getDocumenId());
        FileOutputStream fos = null;
        String fileName = contracts.getTitle() + ".pdf";
        String contractUrl = "/root/miniapp-xjy/app/ys-hks-app/contract/";
        try {
            fos = new FileOutputStream(contractUrl + fileName);
        } catch (FileNotFoundException e) {
            log.error(e.getMessage(), e);
        }
        sdkClient.download(request, fos);
        IOUtils.safeClose(fos);
        File file = new File(contractUrl + fileName);
        XjyOssEnum.CONTRACT.putObject(file, fileName);
        String url = XjyOssEnum.CONTRACT.getSignedUrl(fileName);
        ContractDownLoadRes res = new ContractDownLoadRes();
        res.setDocumentUrl(url);
        return res;
    }

    public ContractsQryRes contractsQry(ContractsQryReq req) {
        PUser user = Subject.get();
        List<Contracts> contractsList = contractsDaoService.queryForApp(user.getId(), req.getState(), req.getSignState());
        ContractsQryRes contractsQryRes = new ContractsQryRes();
        if (contractsList.isEmpty()) {
            return contractsQryRes;
        }
        List<ContractsBo> contractsBos = ContractsMgmtMappings.INSTANCE.contractsList2boList(contractsList);
        contractsQryRes.setContractsBos(contractsBos);
        return contractsQryRes;
    }

    public String QYSnotice(QYSnoticeReq req) {
        if (!StringUtil.isNullOrEmpty(req.getContact())) {
            Contracts contracts = contractsDaoService.qryByContractId(req.getContractId());
            Users users = usersDaoService.selectByMobile(req.getContact());
            if (users.getId().equals(contracts.getPartyIdA())) {
                contracts.setPartySignA("1");
            }
            if (users.getId().equals(contracts.getPartyIdB())) {
                contracts.setPartySignB("1");
            }
            if (users.getId().equals(contracts.getPartyIdC())) {
                contracts.setPartySignC("1");
            }
            if (EnumConst.ContractQYSState.COMPLETE.equals(req.getContractStatus())
                    && EnumConst.ContractQYSState.COMPLETE.equals(req.getCallbackType())) {
                contracts.setState(EnumConst.ContractState.CONTRACT_STATE_2);
            }
            contractsDaoService.updateById(contracts);
        }
        return "SUCCESS";
    }

    public BrowseRes browse(BrowseReq req) {
        BrowseRes res = new BrowseRes();
        //获取合同信息
        Contracts contracts = contractsDaoService.qryById(req.getId());
        SdkClient sdkClient = createQYSClient();
        ContractMiniappViewTicketRequest request = new ContractMiniappViewTicketRequest(contracts.getContractId());
        String response = null;
        try {
            response = sdkClient.service(request);
        } catch (Exception e) {
            throw new BaseSdkException("调用接口错误，错误原因：" + e.getMessage());
        }
        SdkResponse<MiniappTicketResult> result = JSONUtils.toQysResponse(response, MiniappTicketResult.class);
        if (!result.getCode().equals(0)) {
            throw new BaseSdkException("获取合同签署Ticket失败，失败原因：" + result.getCode() + "," + result.getMessage());
        }
        log.info("获取合同签署Ticket成功，Ticket:" + result.getResult().getTicket());
        res.setToken(result.getResult().getTicket());
        return res;
    }

    public static SdkClient createQYSClient() {
        // 初始化sdkClient
        String serverUrl = "https://openapi.qiyuesuo.cn";
        String accessKey = "2T5y2lbw85";
        String accessSecret = "OPaMBDV2dB1K3eC9aMrKArkFRwCPTc";
        SdkClient sdkClient = new SdkClient(serverUrl, accessKey, accessSecret);
        return sdkClient;
    }

    public static Date strToDate(String dateString) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");
        Date date = null;
        try {
            date = formatter.parse(dateString);
            System.out.println(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}
